# 引入适当的模块
import numpy as np
from skimage import io
import matplotlib.pyplot as plt

# 1. 读入RGB狗图: 'dog.jpg'
img = io.imread("dog.jpg")


# 2. 定义一个函数用来把任何一个图像(img)分成(parts)块，翻转，再拼接，最后返回新图像
def reverse_img(img, parts=1):
    # 如果parts等于1, 表示不需要切割, 则直接返回原图
    if parts == 1:
        return img

    # 获得图像的宽度w
    w = img.shape[1]

    # 获得下一句 np.split 需要的切分列表
    # 注意1: 沿着图像轴1, 从0到最后一个像素，需要切(parts)个部分 -> 切分列表所需元素个数: parts+1
    # 注意2: np.linspace生成的数组返回的是浮点数，我们需要整数，所以需要转型
    idx_list = np.linspace(0, w, parts + 1).astype(int)

    # 使用上一步得到的: idx_list 沿着轴1切割图像, 生成切割的子块列表，然后翻转过来(直接用步长就可以实现翻转)
    img_parts = np.split(img, idx_list[::], axis=1)[-1::-1]

    # 把列表中已经翻转过来的子块连接在一起
    new_img = np.concatenate(img_parts, axis=1)
    return new_img  # 返回新图像


ps = [1, 3, 10, 20, 50, 100, 500, 800, 1000]  # 定义要切割的任务列表

fg, ax = plt.subplots(3, 3, figsize=(12, 9))  # 构建3*3的子图画板，宽12高9

for i in range(len(ps)):  # 循环所有切割任务
    # 首先通过 i 获得现在将要绘制的子图 ax[A,B], 赋值给变量a
    # 仔细想一想A与B与i之间的关系
    a = ax[i // 3, i % 3]

    # 用子图绘制结果图像, 直接在imshow中调用 reverse_img 即可
    a.imshow(reverse_img(img, parts=ps[i]))

    # 如果分割任务是1，则给子图添加title 'original'，否则添加分割任务的数字
    if i == 0:
        a.set_title('original')
    else:
        a.set_title(ps[i])

plt.tight_layout()  # 调整子图位置

# 以最紧凑模式保存显示内容到 out.png
plt.savefig('out.png', bbox_inches='tight')
plt.show()